﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PluginInterface;
using Buccontrols;
using System.IO;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Windows.Forms;

namespace Buccaneer
{
    public class AddPluginFormAction : PluginAction
    {
        public AddPluginFormAction()
        {
            base.name = "addform";
            base.func = new ActionFunction(AddForm);
            base.pluginDaddy = MainProgram.MainForm;
            base.exceptions.Add("System.InvalidOperationException", new ActionFunction(AddFormThreadSafe));
        }

        public static void AddForm(string[] args)
        {
            LoadPluginForm frm = new LoadPluginForm(MainProgram.MainForm.selectedPlugin);
            frm.MdiParent = MainProgram.MainForm;
            frm.Name = "LoadPluginForm" + MainProgram.MainForm.MdiChildren.Length.ToString();
            frm.Show();
        }

        public static void AddFormThreadSafe(string[] args)
        {
            MainProgram.MainForm.ActRequest("addform", args);
        }
    }

    public class LoadDirectoryAction : PluginAction
    {
        public LoadDirectoryAction()
        {
            base.name = "loadlibdir";
            base.func = new ActionFunction(LoadLibraryDirectory);
            base.pars.Add("path", "path of the directory containing assemblyfile(s)");
            base.exceptions.Add("Systen.IO.DirectoryNotFoundException", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) The directory was not found!");
                }));
            base.exceptions.Add("System.Exception", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) An error occurred!");
                }));
            base.pluginDaddy = MainProgram.MainForm;
        }

        public void LoadLibraryDirectory(string[] args)
        {
            MainProgram.Plugins.FindPlugins(Options.PluginsFolder);

            int count = MainProgram.Plugins.AvailablePlugins.Count;
            Options.WriteComment("(i) " + count.ToString() + " plugin" + (count == 1 ? " was" : "s were") + " found:");

            foreach (Types.AvailablePlugin pluginOn in MainProgram.Plugins.AvailablePlugins)
            {
                Options.WriteComment(" -  " + pluginOn.Instance.Name);
            }

            MainProgram.selectedPlugin = MainProgram.Plugins.AvailablePlugins.Find(args[0]);
            if (MainProgram.selectedPlugin != null)
            {
                MainProgram.selectedPlugin.Instance.MainInterfaceParent = MainProgram.MainForm;
                MainProgram.selectedPlugin.Instance.MainInterface.Show();
                MainProgram.Plugins.SwitchToPlugin(MainProgram.MainForm.selectedPlugin);
            }
        }
    }

    public class LoadLibraryAction : PluginAction
    {
        public LoadLibraryAction()
        {
            base.name = "loadlib";
            base.func = new ActionFunction(LoadLibrary);
            base.pars.Add("name", "the name of the assemblyfile");
            base.pars.Add("path", "optional: path of assemblyfile");
            base.exceptions.Add("Systen.IO.DirectoryNotFoundException", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) The directory was not found!");
                }));
            base.exceptions.Add("System.Exception", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) An error occurred!");
                }));
            base.pluginDaddy = MainProgram.MainForm;
        }

        public static void LoadLibrary(string[] args)
        {
            if (args.Length >= 2)
                MainProgram.Plugins.AddPlugin(args[1] + args[0]);
            else
                MainProgram.Plugins.AddPlugin(Options.PluginsFolder + args[0]);
        }
    }

    public class LoadStartupAction : PluginAction
    {
        public LoadStartupAction()
        {
            base.name = "loadstartup";
            base.func = new ActionFunction(this.LoadStartup);
            base.pluginDaddy = MainProgram.MainForm;
        }

        public void LoadStartup(string[] args)
        {
            foreach (string s in Options.Settings.Get("BuccOptions.Startup.Plugins").SubTree)
            {
                MainProgram.selectedPlugin = MainProgram.Plugins.LoadPlugin(s);
                if (MainProgram.selectedPlugin != null)
                {
                    Size size = Options.Settings.Get("BuccOptions.Startup.Plugins." + s + ".Size").ValueAsSize();
                    Point point = Options.Settings.Get("BuccOptions.Startup.Plugins." + s + ".Location").ValueAsPoint();
                    //MainProgram.MainForm.AddPlugin(MainProgram.selectedPlugin.Instance);
                    MainProgram.selectedPlugin.Instance.MainInterfaceParent = MainProgram.MainForm;
                    MainProgram.selectedPlugin.Instance.MainInterface.Name = MainProgram.selectedPlugin.Name;
                    MainProgram.selectedPlugin.Instance.Initialize();
                    if (size != new Size()) MainProgram.selectedPlugin.Instance.MainInterface.Size = size;
                    if (point != new Point())
                    {
                        MainProgram.selectedPlugin.Instance.MainInterface.StartPosition = FormStartPosition.Manual;
                        MainProgram.selectedPlugin.Instance.MainInterface.Location = point;
                    }
                    MainProgram.selectedPlugin.Instance.MainInterface.Show();
                    Options.WriteComment("(i) Created PluginForm: " + MainProgram.selectedPlugin.Name);
                    MainProgram.Plugins.SwitchToPlugin(MainProgram.selectedPlugin.Name);
                }
            }
            foreach (string s in Options.Settings.Get("BuccOptions.Startup.Controls").SubTree)
            {
                PluginControl frm = new PluginControl();
                Size size = Options.Settings.Get("BuccOptions.Startup.Controls." + s + ".Size").ValueAsSize();
                Point point = Options.Settings.Get("BuccOptions.Startup.Controls." + s + ".Location").ValueAsPoint();
                switch (s.ToLower())
                {
                    case "menu":
                        frm = new MenuControl();
                        frm.Name = "MenuControl" + MainProgram.MainForm.MdiChildren.Length.ToString();
                        break;
                    case "addressbar":
                        frm = new AddressBarControl();
                        frm.Name = "AddressBarControl" + MainProgram.MainForm.MdiChildren.Length.ToString();
                        break;
                }
                if (size != new Size()) frm.Size = size;
                if (point != new Point())
                {
                    frm.StartPosition = FormStartPosition.Manual;
                    frm.Location = point;
                }
                frm.MdiParent = MainProgram.MainForm;
                frm.Show();
            }
        }
    }

    public class LoadPluginAction : PluginAction
    {
        public LoadPluginAction()
        {
            base.name = "loadplugin";
            base.func = new ActionFunction(LoadPlugin);
            base.pars.Add("name", "the name of the plugin");
            base.exceptions.Add("Systen.IO.DirectoryNotFoundException", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) The directory was not found!");
                }));
            base.exceptions.Add("System.Exception", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) An error occurred!");
                }));
            base.pluginDaddy = MainProgram.MainForm;
        }

        public static void LoadPlugin(string[] args)
        {
            MainProgram.selectedPlugin = MainProgram.Plugins.LoadPlugin(args[0]);
            if (MainProgram.selectedPlugin != null)
            {
                //MainProgram.MainForm.AddPlugin(MainProgram.selectedPlugin.Instance);
                MainProgram.selectedPlugin.Instance.MainInterfaceParent = MainProgram.MainForm;
                MainProgram.selectedPlugin.Instance.MainInterface.Name = MainProgram.selectedPlugin.Name;
                MainProgram.selectedPlugin.Instance.Initialize();
                MainProgram.selectedPlugin.Instance.MainInterface.Show();
                Options.WriteComment("(i) Created PluginForm: " + MainProgram.selectedPlugin.Name);
                MainProgram.Plugins.SwitchToPlugin(MainProgram.selectedPlugin.Name);
            }
        }
    }

    public class UnloadPluginAction : PluginAction
    {
        public UnloadPluginAction()
        {
            base.name = "unloadplugin";
            base.func = new ActionFunction(UnloadPlugin);
            base.pars.Add("name", "the name of the plugin");
            base.exceptions.Add("Systen.IO.DirectoryNotFoundException", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) The directory was not found!");
                }));
            base.exceptions.Add("System.Exception", new ActionFunction(
                delegate(string[] args)
                {
                    Options.WriteComment("(x) An error occurred!");
                }));
            base.pluginDaddy = MainProgram.MainForm;
        }

        public static void UnloadPlugin(string[] args)
        {
            MainProgram.selectedPlugin.Instance.Dispose();
            Options.WriteComment("(i) Removed PluginForm: " + MainProgram.selectedPlugin.Name);
            MainProgram.Plugins.UnloadPlugin(args[0]);
        }
    }

    public class ShowPluginsAction : PluginAction
    {
        public ShowPluginsAction()
        {
            base.name = "showplugins";
            base.func = new ActionFunction(ShowPlugins);
            base.pluginDaddy = MainProgram.MainForm;
        }

        public void ShowPlugins(string[] args)
        {
            int count = MainProgram.Plugins.AvailablePlugins.Count;
            Options.WriteComment("(i) " + count.ToString() + " plugin" + (count == 1 ? " was" : "s were") + " found:");

            foreach (Types.AvailablePlugin pluginOn in MainProgram.Plugins.AvailablePlugins)
            {
                Options.WriteComment(" -  " + pluginOn.Instance.Name);
            }
        }
    }

    public class ActivatePluginAction : PluginAction
    {
        public ActivatePluginAction()
        {
            base.name = "activatePlugin";
            base.func = new ActionFunction(ActivatePlugin);
            base.pars.Add("pluginFormName", "The form to activate");
        }

        public void ActivatePlugin(string[] args)
        {
            string name = Regex.Replace(args[0], @"\d", "");
            MainProgram.selectedPlugin = MainProgram.Plugins.GetPlugin(args[0]);
            MainProgram.Plugins.SwitchToPlugin(MainProgram.selectedPlugin.Name);
        }
    }
}
